/*
* coder  : dzlua
* email  : 505544956@qq.com
* module : trans-client
* path   : src
* file   : main.cpp
* time   : 2018-01-24 13:13:57
*/

#include <evpp/tcp_client.h>
#include <evpp/buffer.h>
#include <evpp/tcp_conn.h>
#include <chrono>

struct Data {
    int64_t time;
    std::string sublib;
    std::string title;
    std::string url;
    std::string type;
    std::string author;
    std::string from;
    std::string content;
    Data() {
        this->time = 0;
    }
    void send(const evpp::TCPConnPtr& conn) {
        evpp::Buffer msg;
        msg.AppendInt64(this->time);
        this->send(this->sublib, msg);
        this->send(this->title, msg);
        this->send(this->url, msg);
        this->send(this->type, msg);
        this->send(this->author, msg);
        this->send(this->from, msg);
        this->send(this->content, msg);
        conn->Send(&msg);
    }
    static int64_t getTimeStamp() {
        std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
        return tp.time_since_epoch().count();
    }
private:
    inline void send(const std::string& str, evpp::Buffer& msg) {
        msg.AppendInt64(str.length());
        msg.Append(str.data(), str.length());
    }
};

class Task {
public:
    Task() {}
    ~Task() {}
public:
    void start() {
    }
    void stop() {
    }
    void push(const std::shared_ptr<Data>& data) {}
    std::shared_ptr<Data> pop() {
        // test
        auto data = std::make_shared<Data>();
        //data->time = data->getTimeStamp();
        //data->sublib = "sougou";
        //data->title = "title";
        data->url = "https://baidu.com";
        //data->type = "it";
        //data->author = "dzlua";
        //data->from = "sougou";
        data->content = "<html>content</html>";
        return data;
    }
};

class Handle {
public:
    Handle() {}
    ~Handle() {}
public:
    void start(const std::string &addr) {
        task_ = std::shared_ptr<Task>();
        loop_ = std::make_shared<evpp::EventLoop>();
        client_ = std::make_shared<evpp::TCPClient>(loop_.get(), addr, "trans-client");
        client_->SetMessageCallback(this->_OnMessageCallback);
        client_->SetConnectionCallback(this->_OnConnectionCallback);
        client_->Connect();
        loop_->Run();
    }
    void stop() {}
protected:
    static void _OnMessageCallback(const evpp::TCPConnPtr& conn, evpp::Buffer* msg) {
        LOG_TRACE << "Receive a message [" << msg->ToString() << "]";
        if (msg->ToString() == "done") {
            auto data = task_->pop();
            data->send(conn);
        }
        msg->Reset();
    }
    static void _OnConnectionCallback(const evpp::TCPConnPtr& conn) {
            if (conn->IsConnected()) {
                LOG_INFO << "Connected to " << conn->remote_addr();
            } else {
                conn->loop()->Stop();
            }
        }
private:
    static std::shared_ptr<evpp::EventLoop> loop_;
    static std::shared_ptr<evpp::TCPClient> client_;
    static std::shared_ptr<Task> task_;
};

std::shared_ptr<Task> Handle::task_ = nullptr;
std::shared_ptr<evpp::EventLoop> Handle::loop_ = nullptr;
std::shared_ptr<evpp::TCPClient> Handle::client_ = nullptr;

int main(int argc, char* argv[]) {
    std::string addr = "127.0.0.1:9099";
    
    if (argc != 2) {
        printf("Usage: %s <host:port>\n", argv[0]);
        printf("  e.g: %s 127.0.0.1:9099\n", argv[0]);
        return 0;
    }

    if (argc == 2) {
        addr = argv[1];
    }

    Handle handle;
    handle.start(addr);
    handle.stop();
    
    return 0;
}

#ifdef WIN32
#include "winmain-inl.h"
#endif